--neutral messages
-- "The battle begins in 1 minute."
-- "The battle begins in 30 seconds.  Prepare yourselves!"
-- "Let the battle begin!"
-- "The (%Faction) flag is now placed at its base."
-- "The flag carriers have become vulnerable to attack!"
-- "The flag carriers have become increasingly vulnerable to attack!"
-- "Time Expired!"
-- "The (%Faction) wins!"

--faction messages
-- "The (%Faction) Flag was picked up by (%Player)!"
-- "The (%Faction) Flag was dropped by (%Player)!"
-- "The (%Faction) Flag was returned to its base by (%Player)!"
-- (%Player) captured the (%Faction) Flag!"
do
    local pvp = pvp
    local COLORS = COLORS
 
    local settings
    local flag1,flag2,debuff
    local debuffCounter
    local playerFaction
    local grabs
 
    --useful strings/patters
	local BG = "wsg"
    local VULNERABLE1 = "The flag carriers have become vulnerable to attack!"
    local VULNERABLE2 = "The flag carriers have become increasingly vulnerable to attack!"
    local ACTION = "The %a+ %alag was (.+) by .+!"
    local CAPTURE = ".+ captured the %a+ %alag!"
	
	--functions
	local UnitHealth = UnitHealth
	local UnitHealthMax = UnitHealthMax
	local UnitExists = UnitExists
	local UnitFactionGroup = UnitFactionGroup
	local RequestBattlefieldScoreData = RequestBattlefieldScoreData
	local strmatch = strmatch
	local floor = floor	
 
 

--------------------------------------------------------------------------------------------------
    local function GetKeys(bar,id)
	--[[
		create and return a table of variables pertaining to the flag carrier
	--]]
        if not bar or not id then return end
        local name = bar.status.text:GetText()
		local keys = {
			["name"] = name,
			["class"] = UnitClass(id),
			["percent"] = bar.info.text:GetText(),
			["health"] = UnitHealth(id),
			["maxhealth"] = UnitHealthMax(id),
			["spec"] = pvp:GetPlayerSpec(name),
        }
		
		return keys	
    end

--------------------------------------------------------------------------------------------------
    local function SetClickText(bar,id)
	--[[
		what is broadcast when clicking on a bar representing a flag carrier
	--]]
        if not bar then return end     
        bar:SetScript("OnMouseDown",
            function(self,button)
                if button == "RightButton" then      
                    --SendChatMessage(pvp:FormatText(settings.clickEFC,GetKeys(bar,id)),"SAY")
					pvp:Broadcast(pvp:FormatText(settings.clickEFC,GetKeys(bar,id)))
                end
            end
        )  
    end
 
--------------------------------------------------------------------------------------------------
    local function GetHealth(flag,id)
	--[[
		represent health of flag carrier
	--]]
        if not flag then return end
  
        if UnitExists(id) then
			flag:SetScript("OnUpdate",
				function(bar)
					local percent
					local health = UnitHealth(id)
					local maxHealth = UnitHealthMax(id)    
					--this should probably be a global func; health,maxHealth being params
					percent = (maxHealth <= 0 and 0) or floor(health/maxHealth*100 + 0.5) 					
					bar.info.text:SetText(percent.."%")      
					bar.status:SetMinMaxValues(0,maxHealth)
					bar.status:SetValue(health)
				end
			)
        end
    end

--------------------------------------------------------------------------------------------------
    local function SetupBar(flag,id)
	--[[
		how to setup the bars used for this battleground
	--]]
        -- horde flag, alliance player: flag1, ArenaTarget1
        -- alliance flag, horde player: flag2, ArenaTarget2
        if not flag then return end
    
        --don't want inf loop (callback for wsg calls this func again)
        local callback = pvp.callback
        pvp.callback = nil
        local mode = (settings.override and BG) or "all"
    
        local factions = {"Alliance","Horde"}
        --reset stuff first
        flag.status.text:SetText(factions[flag.id].." Flag")
        flag.info.text:SetText("")
        flag:SetScript("OnMouseDown",nil)
		flag:SetScript("OnUpdate",nil)
		flag.status:SetMinMaxValues(0,1)
		flag.status:SetValue(1)
		
		--get the saved stuff
        local settings = settings --settings is pvp.settings.wsg  
        local classBar = settings.classBars
        local classFont = settings.classNames
        local infoColor = settings.texture.infoColor
		
		pvp:Log("bar "..flag.id.." "..(id or "nil"))
    
        if not id then --flag is dropped, but not returned
            local color = COLORS[factions[flag.id]]
            pvp:Redraw(mode,flag.id,flag.id) --call Redraw on just this bar
            flag.status:SetStatusBarColor(color.r,color.g,color.b)
            flag.info:SetStatusBarColor(infoColor.r,infoColor.g,infoColor.b)         
        elseif UnitExists(id) then --flag picked up
            local _,class = UnitClass(id)     
            local color = COLORS[class]
            local faction = COLORS[UnitFactionGroup(id)] or infoColor
      
            if settings.faction then
                flag.info:SetStatusBarColor(faction.r, faction.g, faction.b)
            end
  
            --setup status bar
            flag.status.text:SetText(UnitName(id))
            if classBar then flag.status:SetStatusBarColor(color.r,color.g,color.b) end
            if classFont then
                flag.status.text:SetTextColor(color.r,color.g,color.b)
            end

            GetHealth(flag,id)
        
            if UnitFactionGroup(id) == playerFaction then
                pvp:DefaultClickText(flag)
            else
                SetClickText(flag,id)
            end
        else --flag returned/captured
            pvp:Redraw(mode,flag.id,flag.id)
        end
    
        --and restore callback for future redraws
        pvp.callback = callback
    end
 
--------------------------------------------------------------------------------------------------
    local function Setup()
	--[[
		called after Redraw to keep any class/faction color options in tact
	--]]
        SetupBar(flag1,"arena1")
        SetupBar(flag2,"arena2")
    end
 
--------------------------------------------------------------------------------------------------
    local function UpdateDebuff()
	--[[
		create/update the flag carrier debuff countdown
	--]]
        if not settings.debuff then return end
		
		--really not sure if/when these switch off now
		local fa = "\124cff71d5ff\124Hspell:46392\124h[Focused Assault]\124h\124r" --clickable
		local ba = "\124cff71d5ff\124Hspell:46393\124h[Brutal Assault]\124h\124r"
     
        --keep this block separate due to different text at 10 stacks
        if debuffCounter == 10 then
            pvp:Stop(debuff)
            debuff.status.text:SetText(ba.." (x10)")
            debuff.info.text:SetText("")
            return
        end
  
        --stacks 1 through 9 all have similar text
        if not debuff then
            debuff = pvp:ShowFrames(1)
            debuff.func =
                function(bar)
                    bar.info.text:SetText("0:00")
                end
            pvp:Resize()  
            pvp:SetBarAsTimer(debuff,180) --first timer is 3 minutes
            pvp:DefaultClickText(debuff)
            debuffCounter = 1
        elseif debuffCounter < 10 then
            pvp:Stop(debuff)
            pvp:SetBarAsTimer(debuff,60)
            debuffCounter = debuffCounter + 1
        end
  
        debuff.status.text:SetText("Next "..fa.." (x"..debuffCounter..")")  
    end

-------------------------------------------------------------------------------------------------- 
    local function ClearDebuff()
	--[[
		stop/hide/reset debuff bar
	--]]
        pvp:Stop(debuff)
        debuff:Hide()
        pvp:Resize()
        debuff = nil
        debuffCount = 0
    end
	
--------------------------------------------------------------------------------------------------
    local function FactionEvent(action,offensive,defensive)
	--[[
		what to do depending on what the action is and which bars to do it to
		action is the 'verb' of the event that happened
		offensive and defensive are tables with a bar and an id, order depends on the faction of the event
	--]]
        if action == "picked up" then
			pvp:RequestBattlefieldScoreData() --attempt to have efc spec ready to go
            SetupBar(offensive[1],offensive[2])
            grabs = grabs + 1
            if not debuff and grabs >= 2 then
                grabs = 2
                UpdateDebuff()             
            end
            return
        end
    
        if action == "dropped" then
            SetupBar(defensive[1])
            return
        end            
    
        if action == "returned to its base" then
            SetupBar(defensive[1],defensive[2])
            grabs = grabs - 1
            if debuff and grabs <= 0 then
                grabs = 0
                ClearDebuff()
            end
            return
        end
     
        if action == "captured" then
            SetupBar(offensive[1],offensive[2])
            grabs = 0
            if debuff then ClearDebuff() end
            return
        end
         
    end
 
--------------------------------------------------------------------------------------------------
    local function AllianceEvent(event,msg)
	--[[
		how to handle alliance events
	--]]
        local action = strmatch(msg,ACTION) or "captured" --3 of 4 actions are matched with the same pattern
		pvp:Log("AllianceEvent: ".. " ("..action..")")
        FactionEvent(action, {flag2,"arena2"}, {flag1,"arena1"})    
    end
 
--------------------------------------------------------------------------------------------------
    local function HordeEvent(event,msg)
	--[[
		how to handle horde events
	--]]
        local action = strmatch(msg,ACTION) or "captured"
		pvp:Log("HordeEvent: ".. " ("..action..")")
        FactionEvent(action, {flag1,"arena1"}, {flag2,"arena2"})    
    end
	
--------------------------------------------------------------------------------------------------
    local function NeutralEvent(event,msg)
	--[[
		only neutral events to be concerned about are the debuff ones
	--]]
		if msg == VULNERABLE2 or msg == VULNERABLE1 then
			if debuffCount == 0 then UpdateDebuff() end --this is atleast stack 2
			UpdateDebuff() 
			return
		end
    end
	
	
	
--------------------------------------------------------------------------------------------------
    function wsg:Start()
	--[[
		start up the battleground
		get frames used, register events, etc
	--]]
        pvp:Reset()
  
        settings = pvp.settings.wsg
        if not settings.enabled then
            pvp:Log("wsg is disabled.")
            return
        end
         
        pvp.mode = BG        
        playerFaction = UnitFactionGroup("player")
        grabs = 0 --attempt to keep track of when debuff should show
        flag1,flag2 = pvp:ShowFrames(2,true)
        pvp:Redraw()
        pvp:Resize()    
        Setup()
		
        pvp.callback = Setup --called at end of pvp:Redraw(), battleground specific
		pvp.End = End

        wsg:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE",HordeEvent)
        wsg:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE",AllianceEvent)
        wsg:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL",NeutralEvent)
		
		pvp:Log(BG.." initialized")
    end
	
--------------------------------------------------------------------------------------------------
    function wsg:End()
	--[[
		close the battleground
	--]]
        wsg:UnregisterEvent("CHAT_MSG_BG_SYSTEM_HORDE")
        wsg:UnregisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE")
        wsg:UnregisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL")
  
        if debuff then pvp:Stop(debuff); debuff=nil end --nil debuff.func in reset
  
        pvp.callback = nil
        pvp.mode = "all"
  
        pvp:Reset()
    end

--------------------------------------------------------------------------------------------------
	function pvp:wsgOptionsTable(t)
	--[[
		options specific to this battleground
	--]]
		local features = t.args.features
	  
		local desc = "Text that will be sent to chat when right clicking on the enemy flag carrier bar.\n\n"
		desc = desc.."|cffffcc00Keys|r\n"
		desc = desc.."name, class, spec, altclass, altspec, health, maxhealth, percent"
	   
		features.args.debuff = {
			name = "Focused Assault",
			desc = "Show Focused Assault debuff timer",
			width = 'full',
			type = 'toggle',
			order = 12,
			get = function()
				return pvp.settings.wsg.debuff
			end,
			set = function(_,value)
				pvp.settings.wsg.debuff = value
				local bar = pvp.frame.bars[5]
				if pvp.mode == BG then
					if not value then
						bar:Hide()
						pvp:Resize()
					end
				end       
			end,
		}
		features.args.classBars = {
			name = "Color bars by class",
			desc = "Color bars by the class color of the flag carrier.",
			type = 'toggle',
			order = 13, 
			get = function()
				return pvp.settings.wsg.classBars
			end,
			set = function(_,value)
				pvp.settings.wsg.classBars = value
				local mode = (pvp.settings.wsg.override and BG) or "all"
				pvp:Redraw(mode)
			end
		}
		features.args.classNames = {
			name = "Color names by class",
			desc = "Color names by the class colors of the flag carrier.",
			type = 'toggle',
			order = 14,
			get = function()
				return pvp.settings.wsg.classNames
			end,
			set = function(_,value)
				pvp.settings.wsg.classNames = value
				local mode = (pvp.settings.wsg.override and BG) or "all"
				pvp:Redraw(mode)
			end
		}
		features.args.faction = {
			name = "Color info by faction",
			desc = "Color the info area by the faction of the flag carrier.",
			type = 'toggle',
			order = 15,
			get = function()
				return pvp.settings.wsg.faction
			end,
			set = function(_,value)
				pvp.settings.wsg.faction = value
				local mode = (pvp.settings.wsg.override and BG) or "all"
				pvp:Redraw(mode)
			end
		}
		features.args.clickEFC = {
			name = "EFC message",
			desc = desc,
			type = 'input',
			width='full',
			order = 16,
			get = function()
				return pvp:Unparse(pvp.settings.wsg.clickEFC)                  
			end,
			set = function(self,value)
				pvp.settings.wsg.clickEFC = pvp:Parse(value)
				if pvp.mode == BG then Setup() end
			end,
		}    
		features.args.testEFC = {
			name = "Test",
			desc = "Test the message.",
			type = 'execute',
			order = 17,
			func = function()
				local keys = {
					["name"] = "Testwarrior",
					["class"] = "Warrior",
					["spec"] = "Protection",
					["altclass"] = pvp.settings.alt.class["Warrior"],
					["altspec"] = pvp.settings.alt.spec["Warrior"]["Protection"],
					["health"] = 450000,
					["maxhealth"] = 500000,
					["percent"] = "90%",
				}
				local msg = pvp:FormatText(pvp.settings.wsg.clickEFC,keys)
				pvp:TestInput(msg)                  
			end,
		}
		features.args.resetEFC = {
			name = "Reset",
			desc = "Reset message to default.",
			type = 'execute',
			order = 18,
			func = function()
				pvp.settings.wsg.clickEFC = {"EFC: %s - %s",{"name","percent"}}
				if pvp.mode == BG then Setup() end
			end
		}

		return t
	end 
end 